using UnityEngine;

public class ManagerZombies : MonoBehaviour, IZombieListener
{
	public static int kills;

	public static int aliveSceneTotal;

	[Tooltip("Задержка перед активацией")]
	public float timeStart;

	[Tooltip("Количество добавляемых существ")]
	public int quantity = 1;

	[Tooltip("Временной промежуток для добавления")]
	public float periodAdd = 2f;

	[Tooltip("Максимальное кол-во живых одновременно на сцене")]
	public int limitOnStage = 7;

	public int total = 1000;

	public bool randomEntity = true;

	public ZombieWithCharacter[] zombies = new ZombieWithCharacter[0];

	[Space(8f)]
	[Range(0.5f, 2f)]
	public float scaleSpeedMove = 1f;

	[Range(0.5f, 2f)]
	public float scaleSpeedMoveMax = 1f;

	[Space(8f)]
	public bool randomPosition = true;

	public Vector2[] positions;

	public float periodScale = 1f;

	private float timerAdd;

	[HideInInspector]
	public int numAttack;

	public int numBreakLeg = -5;

	private float priorityTotal;

	private int currentPosition;

	private ManagerZombies[] managers = new ManagerZombies[0];

	private ZombieInHome newZombie;

	private Vector2 position;

	private int[] zombieBreakLeg = new int[20];

	public int totalAlive => numAttack + total;

	private void OnDrawGizmos()
	{
		if (base.enabled)
		{
			Gizmos.color = new Color(0f, 0f, 0f, 0.1f);
			for (int i = 0; i < positions.Length; i++)
			{
				Gizmos.DrawWireSphere(base.transform.TransformPoint(positions[i]), 0.25f);
			}
		}
	}

	private void OnDrawGizmosSelected()
	{
		if (base.enabled)
		{
			Gizmos.color = new Color(0f, 0f, 0f);
			for (int i = 0; i < positions.Length; i++)
			{
				Gizmos.DrawWireSphere(base.transform.TransformPoint(positions[i]), 0.25f);
			}
			for (int j = 0; j < zombies.Length; j++)
			{
				zombies[j].priority = Mathf.Abs(zombies[j].priority);
			}
		}
	}

	private void Awake()
	{
		kills = 0;
		aliveSceneTotal = 0;
		for (int i = 0; i < zombies.Length; i++)
		{
			zombies[i].SetLowerPriority(zombies, total);
		}
	}

	private void Start()
	{
		aliveSceneTotal += total;
		managers = base.gameObject.GetComponents<ManagerZombies>();
		numAttack = 0;
		timerAdd = periodAdd;
		limitOnStage = Mathf.Min(limitOnStage, total);
		if (randomPosition)
		{
			currentPosition = UnityEngine.Random.Range(0, positions.Length);
		}
		if (timeStart == 0f && periodAdd == 0f)
		{
			Update();
		}
	}

	public void CreateEntity(int numZombie)
	{
		if (zombies.Length != 0 && total != 0)
		{
			numZombie = Mathf.Min(numZombie, limitOnStage - numAttack);
			int num = 0;
			for (int i = 0; i < numZombie; i++)
			{
				if (total <= 0)
				{
					break;
				}
				priorityTotal = 0f;
				for (int j = 0; j < zombies.Length; j++)
				{
					zombies[j].rangePriorityMin = priorityTotal;
					zombies[j].rangePriorityMax = priorityTotal + zombies[j].priority;
					priorityTotal += zombies[j].priority;
				}
				float num2 = UnityEngine.Random.value * priorityTotal;
				for (num = 0; num < zombies.Length; num++)
				{
					if (zombies[num].rangePriorityMin < num2 && num2 <= zombies[num].rangePriorityMax)
					{
						if (!randomEntity)
						{
							zombies[num].LowerPriority();
						}
						break;
					}
				}
				num = Mathf.Min(num, zombies.Length - 1);
				newZombie = UnityEngine.Object.Instantiate(zombies[num].zombie, base.transform.TransformPoint(positions[currentPosition]), Quaternion.identity);
				newZombie.eventListener = this;
				newZombie.SetScaleSpeed(UnityEngine.Random.Range(scaleSpeedMove, scaleSpeedMoveMax));
				newZombie.character = zombies[num].characters;
				currentPosition++;
				currentPosition = Mathf.FloorToInt(Mathf.Repeat(currentPosition, positions.Length));
				total--;
				numAttack++;
			}
		}
		if (total != 0 || managers.Length < 2 || limitOnStage == 0)
		{
			return;
		}
		int num3 = limitOnStage / (managers.Length - 1);
		limitOnStage = 0;
		int num4 = 0;
		while (num3 >= 1 && num4 < managers.Length)
		{
			if (managers[num4].total != 0 && managers[num4] != this)
			{
				managers[num4].limitOnStage += num3;
			}
			num4++;
		}
	}

	private void Update()
	{
		if (numAttack < limitOnStage && quantity != 0 && total != 0 && Time.timeScale != 0f)
		{
			timerAdd += Time.deltaTime / Time.timeScale;
			if (timerAdd >= (timeStart + periodAdd) * periodScale)
			{
				timeStart = 0f;
				timerAdd = 0f;
				CreateEntity(quantity);
			}
		}
	}

	public void OnSwitchStandBreakLeg(ZombieInHome zombie)
	{
		numBreakLeg++;
		numBreakLeg %= zombieBreakLeg.Length;
		if (numBreakLeg >= 0)
		{
			zombieBreakLeg[numBreakLeg] = zombie.GetInstanceID();
			limitOnStage++;
		}
	}

	public void OnZombieDeath(ZombieInHome zombie)
	{
		kills++;
		RemoveZombie(zombie);
	}

	public void OnZombieDestroy(ZombieInHome zombie)
	{
		if (!zombie.isDead)
		{
			RemoveZombie(zombie);
		}
	}

	private void RemoveZombie(ZombieInHome zombie)
	{
		aliveSceneTotal = Mathf.Max(0, aliveSceneTotal - 1);
		numAttack = Mathf.Max(0, numAttack - 1);
		if (numAttack == 0)
		{
			timerAdd = Mathf.Min(timerAdd, periodAdd * 0.4f);
		}
		int num = 0;
		while (true)
		{
			if (num < zombieBreakLeg.Length)
			{
				if (zombieBreakLeg[num] == zombie.GetInstanceID())
				{
					break;
				}
				num++;
				continue;
			}
			return;
		}
		limitOnStage--;
		zombieBreakLeg[num] = 0;
	}

	public void AddTimePeriod(float time)
	{
		if (periodAdd > 2f)
		{
			periodAdd += time;
			periodAdd = Mathf.Floor(periodAdd * 1000f) / 1000f;
		}
	}
}
